﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using CalculatorLogic.Basic_Math;
using CalculatorLogic.Exponentiation;
using CalculatorLogic.Trignometric_Math;

namespace CalculatorLogic
{
     public class PostfixSolver
    {
        public string Solve(string postfixExp)
        {
            Stack<string> stack = new Stack<string>();
            TokenHelper tokenHelper = new TokenHelper();

            Addition addition = new Addition();
            Subtraction subtraction = new Subtraction();
            Multiplication multiplication = new Multiplication();
            Division division = new Division();
            Power power = new Power();
            Sine sin = new Sine();
            Cosine cos = new Cosine();
            Tangent tan = new Tangent();
            Cotangent cot = new Cotangent();
            Cosecant csc = new Cosecant();
            Secant sec = new Secant();
            Logarithmic_Math.NaturalLog ln = new Logarithmic_Math.NaturalLog();
            Logarithmic_Math.Log log = new Logarithmic_Math.Log();
            
            
            Equation additionEquation = new Equation() { Input = new string[2] };
            Equation subtractionEquation = new Equation() { Input = new string[2] };
            Equation multiplicationEquation = new Equation() { Input = new string[2] };
            Equation divisionEquation = new Equation() { Input = new string[2] };
            Equation powerEquation = new Equation() { Input = new string[2] };
            Equation sinEquation = new Equation() { Input = new string[2] };
            Equation cosEquation = new Equation() { Input = new string[2] };
            Equation tanEquation = new Equation() { Input = new string[2] };
            Equation cotEquation = new Equation() { Input = new string[2] };
            Equation cscEquation = new Equation() { Input = new string[2] };
            Equation secEquation = new Equation() { Input = new string[2] };
            Equation lnEquation = new Equation() { Input = new string[2] };
            Equation logEquation = new Equation() { Input = new string[2] };

            string temp;

            string[] expression = postfixExp.Split(' ');

            foreach (string currentToken in expression)
            {
                if (tokenHelper.IsNumber(currentToken))
                {
                    stack.Push(currentToken);
                }
                
                if (currentToken == "+")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    additionEquation.Input[0] = temp;
                    additionEquation.Input[1] = stack.Peek();

                    addition.Apply(additionEquation);
                    string retVal = additionEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "-")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    subtractionEquation.Input[0] = temp;
                    subtractionEquation.Input[1] = stack.Peek();

                    subtraction.Apply(subtractionEquation);
                    string retVal = subtractionEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "*")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    multiplicationEquation.Input[0] = temp;
                    multiplicationEquation.Input[1] = stack.Peek();

                    multiplication.Apply(multiplicationEquation);
                    string retVal = multiplicationEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "/")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    divisionEquation.Input[0] = temp;
                    divisionEquation.Input[1] = stack.Peek();

                    division.Apply(divisionEquation);
                    string retVal = divisionEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "^")
                {
                    temp = stack.Peek();
                    stack.Pop();
                    powerEquation.Input[0] = temp;
                    powerEquation.Input[1] = stack.Peek();

                    power.Apply(powerEquation);
                    string retVal = powerEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "SIN")
                {
                    sinEquation.Input[0] = stack.Peek();
                    sin.Apply(sinEquation);
                    string retVal = sinEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "COS")
                {
                    cosEquation.Input[0] = stack.Peek();
                    cos.Apply(cosEquation);
                    string retVal = cosEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "TAN")
                {
                    tanEquation.Input[0] = stack.Peek();
                    tan.Apply(tanEquation);
                    string retVal = tanEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "COT")
                {
                    cotEquation.Input[0] = stack.Peek();
                    cot.Apply(cotEquation);
                    string retVal = cotEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "CSC")
                {
                    cscEquation.Input[0] = stack.Peek();
                    csc.Apply(cscEquation);
                    string retVal = cscEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "SEC")
                {
                    secEquation.Input[0] = stack.Peek();
                    sec.Apply(secEquation);
                    string retVal = secEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "LN")
                {
                    lnEquation.Input[0] = stack.Peek();
                    ln.Apply(lnEquation);
                    string retVal = lnEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

                if (currentToken == "LOG")
                {
                    logEquation.Input[0] = stack.Peek();
                    log.Apply(logEquation);
                    string retVal = logEquation.Solved;

                    stack.Pop();
                    stack.Push(retVal);
                }

            }
            if (stack.Count > 0)
            {
                return stack.Peek();
            }
            else
            {
                return "0";
            }
        }

    }
}
